iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
0

本文接續前一篇文章Day5

今天的code會從
https://github.com/mars1120/jetpackMvvmDemo/tree/Databinding
開branch繼續往下修改

今天會將click事件改成databinding型式

首先先替textview新增一個click事件

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        
        ...
        
        val tv: TextView = activity!!.findViewById(R.id.message)
        tv.setOnClickListener {
            previewViewModel.message++
        }
    }

功能是textview點擊以後 顯示的文字訊息會變更
例如變成
message:0 -> message:1 -> message:2

接著馬上來運行專案
會發現點擊以後資料並沒有更新

那我們有兩個辦法來通知UI要更新數據
第一個是數據變更以後呼叫binding().invalidateAll()

但如果每次更新都要呼叫一次也太麻煩
所以接著要導入liveData讓他自動通知

先來修改viewModel

PreviewViewModel.kt

class PreviewViewModel : ViewModel() {
    private val _message = MutableLiveData(0)
    val message: LiveData<Int> = _message
    fun onUpdateMessage(int: Int) {
        _message.value = int
    }
}

接著調整fragment

PreviewFragment.kt

  override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        var binding: PreviewFragmentBinding =
            DataBindingUtil.inflate(inflater, R.layout.preview_fragment, container, false)
        var rootView: View = binding.root
        // setting values to model
        binding.viewModel = previewViewModel
        //注意要跟生命週期綁定 不然數據不會更新
        binding.setLifecycleOwner(this)
        return rootView
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        previewViewModel.onUpdateMessage(getArguments()?.getInt(ARG_PAGE) ?: 0)
        val tv: TextView = activity!!.findViewById(R.id.message)
        tv.setOnClickListener {
            var mMessage = previewViewModel.message.value
            previewViewModel.onUpdateMessage(mMessage!! + 1)
        }

接著我們把click行為也轉移到viewModel去

PreviewViewModel.kt

  fun onClick() {
        _message.value = _message.value!! + 1
    }

Fragment的click宣告就可以移掉了

PreviewFragment.kt

 override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        previewViewModel.onUpdateMessage(getArguments()?.getInt(ARG_PAGE) ?: 0)
      }

接著去xml串接
preview_fragment.xml

<TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{`message:`+String.valueOf(viewModel.message)}"
        android:onClick="@{() -> viewModel.onClick()}"
 />

然後發現fragment頁變得前所未有的清爽(?

那如果想要綁定更多行為呢?
例如說今天我想要textview根據message的數字去改變顯示的顏色

先去build.gradle 新增plugin
build.gradle(module:app)

apply plugin: 'kotlin-kapt'
...
android {
...

接著新增一個BindingAdapters.kt

BindingAdapters.kt

@BindingAdapter("app:textCurrentColor")
fun textCurrentColor(view: View, intMessage: Int) {
    val colorBlack = ContextCompat.getColor(view.context, android.R.color.black)
    val colorPrimary = ContextCompat.getColor(view.context, R.color.colorPrimary)
    if (intMessage > 5)
        (view as TextView).setTextColor(colorPrimary)
    else
        (view as TextView).setTextColor(colorBlack)
}

fun名稱自訂 不要重複就可
@BindingAdapter("XXXXX")
決定在xml顯示的名稱

接著去xml更新textview

preview_fragment.xml

        <TextView
                android:id="@+id/message"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{`message:`+String.valueOf(viewModel.message)}"
                android:onClick="@{() -> viewModel.onClick()}"
                app:textCurrentColor="@{viewModel.message}"
               />

這個功能是點擊一定次數後文字顏色會改變

這樣就完成雙向綁定了

今天的代碼
https://github.com/mars1120/jetpackMvvmDemo/tree/databinding-2


上一篇
Day5 dataBinding - 1
下一篇
Day7 MVVM專案-1
系列文
Android × CI/CD 如何用基本的MVVM專案實現 CI/CD 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言